﻿#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <vector>
#include <functional>
#include <stack>
#include <mutex>
#include <string>
#include <unordered_map>
using namespace std;
struct Date
{
	int _year;
	int _month;
	int _day;

	Date(int year = 1, int month = 1, int day = 1)
		:_year(year)
		, _month(month)
		, _day(day)
	{}

	~Date()
	{
		cout << "~Date()" << endl;
	}
};

namespace xz
{
	template<class T>
	class auto_ptr
	{
	public:
		auto_ptr(T* ptr)
			: _ptr(ptr)
		{}
		auto_ptr(auto_ptr<T>& sp)
			:_ptr(sp._ptr)
		{
			// 管理权转移
			sp._ptr = nullptr;
		}
		auto_ptr<T>& operator=(auto_ptr<T>& ap)
		{
			// 检测是否为⾃⼰给⾃⼰赋值
			if (this != &ap)
			{
				// 释放当前对象中资源
				if (_ptr)
					delete _ptr;
				// 转移ap中资源到当前对象中
				_ptr = ap._ptr;
				ap._ptr = NULL;
			}
			return*this;
		}
		~auto_ptr()
		{
			if (_ptr)
			{
				cout << "delete:" << _ptr << endl;
				delete _ptr;
			}
		}
		// 像指针⼀样使⽤
		T& operator*()
		{
			return *_ptr;
		}
		T* operator->()
		{
			return _ptr;
		}
	private:
		T* _ptr;
	};

	template<class T>
	class unique_ptr
	{
	public:
		explicit unique_ptr(T* ptr)
			:_ptr(ptr)
		{}
		~unique_ptr()
		{
			if (_ptr)
			{
				cout << "delete:" << _ptr << endl;
				delete _ptr;
			}
		}
		// 像指针⼀样使⽤
		T& operator*()
		{
			return *_ptr;
		}
		T* operator->()
		{
			return _ptr;
		}
		unique_ptr(const unique_ptr<T>& sp) = delete;
		unique_ptr<T>& operator=(const unique_ptr<T>& sp) = delete;
		unique_ptr(unique_ptr<T>&& sp)
			:_ptr(sp._ptr)
		{
			sp._ptr = nullptr;
		}
		unique_ptr<T>& operator=(unique_ptr<T>&& sp)
		{
			delete _ptr;
			_ptr = sp._ptr;
			sp._ptr = nullptr;
		}
	private:
		T* _ptr;
	};
	template<class T>
	class shared_ptr
	{
	public:
		explicit shared_ptr(T* ptr = nullptr)
			:_ptr(ptr)
			, _pcount(new atomic<int>(1))
		{}
		template<class D>
		shared_ptr(T* ptr, D del)
			: _ptr(ptr)
			, _pcount(new int(1))
			, _del(del)
		{}
		shared_ptr(const shared_ptr<T>& sp)
			:_ptr(sp._ptr)
			, _pcount(sp._pcount)
			, _del(sp._del)
		{
			++(*_pcount);
		}
		void release()
		{
			if (--(*_pcount) == 0)
			{
				// 最后⼀个管理的对象，释放资源
				_del(_ptr);
				delete _pcount;
				_ptr = nullptr;
				_pcount = nullptr;
			}
		}
		shared_ptr<T>& operator=(const shared_ptr<T>& sp)
		{
			if (_ptr != sp._ptr)
			{
				release();
				_ptr = sp._ptr;
				_pcount = sp._pcount;
				++(*_pcount);
				_del = sp._del;
			}
			return*this;
		}
		~shared_ptr()
		{
			release();
		}
		T* get() const
		{
			return _ptr;
		}
		int use_count() const
		{
			return *_pcount;
		}
		T& operator*()
		{
			return *_ptr;
		}
		T* operator->()
		{
			return _ptr;
		}
	private:
		T* _ptr;
		//int* _pcount;
		atomic<int>* _pcount;
		function<void(T*)> _del = [](T* ptr) {delete ptr; };
	};
	// 需要注意的是我们这⾥实现的shared_ptr和weak_ptr都是以最简洁的⽅式实现的，
	// 只能满⾜基本的功能，这⾥的weak_ptr lock等功能是⽆法实现的，想要实现就要
	// 把shared_ptr和weak_ptr⼀起改了，把引⽤计数拿出来放到⼀个单独类型，shared_ptr
	// 和weak_ptr都要存储指向这个类的对象才能实现，有兴趣可以去翻翻源代码
	template<class T>
	class weak_ptr
	{
	public:
		weak_ptr()
		{}
		weak_ptr(const shared_ptr<T>& sp)
			:_ptr(sp.get())
		{}
		weak_ptr<T>& operator=(const shared_ptr<T>& sp)
		{
			_ptr = sp.get();
			return *this;
		}
	private:
		T* _ptr = nullptr;
	};
}
//int main()
//{
//	xz::auto_ptr<Date> ap1(new Date);
//	// 拷⻉时，管理权限转移，被拷⻉对象ap1悬空
//	xz::auto_ptr<Date> ap2(ap1);
//	// 空指针访问，ap1对象已经悬空
//	//ap1->_year++;
//	xz::unique_ptr<Date> up1(new Date);
//	// 不⽀持拷⻉
//	//unique_ptr<Date> up2(up1);
//	// ⽀持移动，但是移动后up1也悬空，所以使⽤移动要谨慎
//	xz::unique_ptr<Date> up3(move(up1));
//	xz::shared_ptr<Date> sp1(new Date);
//	// ⽀持拷⻉
//	xz::shared_ptr<Date> sp2(sp1);
//	xz::shared_ptr<Date> sp3(sp2);
//	cout << sp1.use_count() << endl;
//	sp1->_year++;
//	cout << sp1->_year << endl;
//	cout << sp2->_year << endl;
//	cout << sp3->_year << endl;
//	return 0;
//}



struct AA
{
	int _a1 = 0;
	int _a2 = 0;

	~AA()
	{
		cout << "~AA()" << endl;
	}
};
int main()
{
	xz::shared_ptr<AA> p(new AA);
	const size_t n = 100000;

	mutex mtx;
	auto func = [&]()
		{
			for (size_t i = 0; i < n; ++i)
			{
				// 这⾥智能指针拷⻉会++计数
				xz::shared_ptr<AA> copy(p);
				{
					unique_lock<mutex> lk(mtx);
					copy->_a1++;
					copy->_a2++;
				}
			}
		};

	thread t1(func);
	thread t2(func);

	t1.join();
	t2.join();

	cout << p->_a1 << endl;
	cout << p->_a2 << endl;

	cout << p.use_count() << endl;

	return 0;
}


//int main()
//{
//	std::shared_ptr<string> sp1(new string("111111"));
//	std::shared_ptr<string> sp2(sp1);
//	std::weak_ptr<string> wp = sp1;
//	cout << wp.expired() << endl;
//	cout << wp.use_count() << endl;
//
//	// sp1和sp2都指向了其他资源，则weak_ptr就过期了
//	sp1 = make_shared<string>("222222");
//	cout << wp.expired() << endl;
//	cout << wp.use_count() << endl;
//
//	sp2 = make_shared<string>("333333");
//	cout << wp.expired() << endl;
//	cout << wp.use_count() << endl;
//
//	wp = sp1;
//	//std::shared_ptr<string> sp3 = wp.lock();
//	auto sp3 = wp.lock();
//	cout << wp.expired() << endl;
//	cout << wp.use_count() << endl;
//
//	*sp3 += "###";
//	cout << *sp1 << endl;
//
//	return 0;
//}


//struct ListNode
//{
//	int _data;
//
//	std::shared_ptr<ListNode> _next;
//	std::shared_ptr<ListNode> _prev;
//
//	// 这⾥改成weak_ptr，当n1->_next = n2;绑定shared_ptr时
//	// 不增加n2的引⽤计数，不参与资源释放的管理，就不会形成循环引⽤了
//	/*std::weak_ptr<ListNode> _next;
//	std::weak_ptr<ListNode> _prev;*/
//
//	~ListNode()
//	{
//		cout << "~ListNode()" << endl;
//	}
//};
//int main()
//{
//	// 循环引⽤ -- 内存泄露
//	std::shared_ptr<ListNode> n1(new ListNode);
//	std::shared_ptr<ListNode> n2(new ListNode);
//
//	cout << n1.use_count() << endl;
//	cout << n2.use_count() << endl;
//
//	n1->_next = n2;
//	n2->_prev = n1;
//
//	cout << n1.use_count() << endl;
//	cout << n2.use_count() << endl;
//
//	// weak_ptr不⽀持管理资源，不⽀持RAII
//	// weak_ptr是专⻔绑定shared_ptr，不增加他的引⽤计数，作为⼀些场景的辅助管理
//	//std::weak_ptr<ListNode> wp(new ListNode);
//
//	return 0;
//}


//void ShowList()
//{
//	cout << endl;
//}
//template <class T, class ...Args>
//void ShowList(T x, Args... args)
//{
//	cout << x << " ";
//	ShowList(args...); 
//}
//
//// 编译时递归推导解析参数
//template <class ...Args>
//void Print(Args... args)
//{
//	// args是N个参数的参数包
//	// 调用ShowList,参数包的第一个传给x,
//	// 剩下N-1传给第二个参数包
//	ShowList(args...);
//}
//
//int main()
//{
//	Print(1, string("xxxxx"), 2.2);
//
//	return 0;
//}




//int main()
//{
//	auto_ptr<Date> ap1(new Date);
//	//拷贝时，管理权限转移，被拷贝对象ap1悬空
//	auto_ptr<Date> ap2(ap1);
//
//	// 空指针访问，ap1对象已经悬空
//	//ap1->_year++;
//
//	unique_ptr<Date> up1(new Date);
//	// 不⽀持拷贝
//	//unique_ptr<Date> up2(up1);
//	// ⽀持移动，但是移动后up1也悬空，所以使⽤移动要谨慎
//	unique_ptr<Date> up3(move(up1));
//
//	shared_ptr<Date> sp1(new Date);
//	// ⽀持拷贝
//	shared_ptr<Date> sp2(sp1);
//	shared_ptr<Date> sp3(sp2);
//	cout << sp1.use_count() << endl;
//	sp1->_year++;
//	cout << sp1->_year << endl;
//	cout << sp2->_year << endl;
//	cout << sp3->_year << endl;
//
//	// ⽀持移动，但是移动后sp1也悬空，所以使⽤移动要谨慎
//	shared_ptr<Date> sp4(move(sp1));
//
//	return 0;
//}

//template<class T>
//void DeleteArrayFunc(T* ptr)
//{
//	delete[] ptr;
//} 
//template<class T>
//class DeleteArray
//{
//	public:
//	void operator()(T* ptr)
//	{
//		delete[] ptr;
//	}
//};
//class Fclose
//{
//	public:
//	void operator()(FILE* ptr)
//	{
//		cout << "fclose:" << ptr << endl;
//		fclose(ptr);
//	}
//};
//int main()
//{
//	// 这样实现程序会崩溃
//	// unique_ptr<Date> up1(new Date[10]);
//	// shared_ptr<Date> sp1(new Date[10]);
//	// 解决⽅案1
//	// 因为new[]经常使⽤，所以unique_ptr和shared_ptr
//	// 实现了⼀个特化版本，这个特化版本析构时⽤的delete[]
//	unique_ptr<Date[]> up1(new Date[5]);
//	shared_ptr<Date[]> sp1(new Date[5]);
//	// 解决⽅案2
//	// 仿函数对象做删除器
//	//unique_ptr<Date, DeleteArray<Date>> up2(new Date[5], DeleteArray<Date>());
//	// unique_ptr和shared_ptr⽀持删除器的⽅式有所不同
//	// unique_ptr是在类模板参数⽀持的，shared_ptr是构造函数参数⽀持的
//	// 这⾥没有使⽤相同的⽅式还是挺坑的
//	// 使⽤仿函数unique_ptr可以不在构造函数传递，因为仿函数类型构造的对象直接就可以调⽤
//	// 但是下⾯的函数指针和lambda的类型不可以
//	unique_ptr<Date, DeleteArray<Date>> up2(new Date[5]);
//	shared_ptr<Date> sp2(new Date[5], DeleteArray<Date>());
//	// 函数指针做删除器
//	unique_ptr<Date, void(*)(Date*)> up3(new Date[5], DeleteArrayFunc<Date>);
//	shared_ptr<Date> sp3(new Date[5], DeleteArrayFunc<Date>);
//	// lambda表达式做删除器
//	auto delArrOBJ = [](Date* ptr) {delete[] ptr; };
//	unique_ptr<Date, decltype(delArrOBJ)> up4(new Date[5], delArrOBJ);
//	shared_ptr<Date> sp4(new Date[5], delArrOBJ);
//	// 实现其他资源管理的删除器
//	shared_ptr<FILE> sp5(fopen("Test.cpp", "r"), Fclose());
//	shared_ptr<FILE> sp6(fopen("Test.cpp", "r"), [](FILE* ptr) {
//		cout << "fclose:" << ptr << endl;
//		fclose(ptr);
//		});
//	return 0;
//}
//int main()
//{
//	shared_ptr<Date> sp1(new Date(2024, 9, 11));
//	shared_ptr<Date> sp2 = make_shared<Date>(2024, 9, 11);
//	auto sp3 = make_shared<Date>(2024, 9, 11);
//	shared_ptr<Date> sp4;
//	// if (sp1.operator bool())
//	if (sp1)
//		cout << "sp1 is not nullptr" << endl;
//	if (!sp4)
//		cout << "sp1 is nullptr" << endl;
//	// 报错
//	shared_ptr<Date> sp5 = new Date(2024, 9, 11);
//	unique_ptr<Date> sp6 = new Date(2024, 9, 11);
//	return 0;
//}



//template<class T>
//class SmartPtr
//{
//	public:
//	// RAII
//	SmartPtr(T* ptr)
//		: _ptr(ptr)
//	{}
//	~SmartPtr()
//	{
//		cout << "delete[] " << _ptr << endl;
//		delete[] _ptr;
//	} 
//	// 重载运算符，模拟指针的⾏为，⽅便访问资源
//	T& operator*()
//	{
//		return *_ptr;
//	} 
//	T* operator->()
//	{
//		return _ptr;
//	} 
//	T& operator[](size_t i)
//	{
//		return _ptr[i];
//	}
//private:
//	T* _ptr;
//};
//double Divide(int a, int b)
//{
//	// 当b == 0时抛出异常
//	if (b == 0)
//	{
//		throw "Divide by zero condition!";
//	} 
//	else
//	{
//		return (double)a / (double)b;
//	}
//} 
//void Func()
//{
//	// 这⾥使⽤RAII的智能指针类管理new出来的数组以后，程序简单多了
//	SmartPtr<int> sp1 = new int[10];
//	SmartPtr<int> sp2 = new int[10];
//	for (size_t i = 0; i < 10; i++)
//	{
//		sp1[i] = sp2[i] = i;
//	} 
//	int len, time;
//	cin >> len >> time;
//	cout << Divide(len, time) << endl;
//} 
//int main()
//{
//	try
//	{
//		Func();
//	} 
//	catch(const char* errmsg)
//	{
//		cout << errmsg << endl;
//	} 
//	catch(const exception & e)
//	{
//		cout << e.what() << endl;
//	} 
//	catch(...)
//	{
//		cout << "未知异常" << endl;
//	} 
//	return 0;
//}



//double Divide(int a, int b)
//{
//	// 当b == 0时抛出异常
//	if (b == 0)
//	{
//		throw "Divide by zero condition!";
//	} 
//	else
//	{
//		return (double)a / (double)b;
//	}
//} 
//void Func()
//	{
//		// 这⾥可以看到如果发⽣除0错误抛出异常，另外下⾯的array和array2没有得到释放。
//		// 所以这⾥捕获异常后并不处理异常，异常还是交给外⾯处理，这⾥捕获了再重新抛出去。
//		// 但是如果array2new的时候抛异常呢，就还需要套⼀层捕获释放逻辑，这⾥更好解决⽅案
//		// 是智能指针，否则代码太戳了
//		int* array1 = new int[10];
//		int* array2 = new int[10]; // 抛异常呢
//		try
//		{
//			int len, time;
//			cin >> len >> time;
//			cout << Divide(len, time) << endl;
//		} 
//		catch(...)
//		{
//			cout << "delete []" << array1 << endl;
//			cout << "delete []" << array2 << endl;
//			delete[] array1;
//			delete[] array2;
//			throw; // 异常重新抛出，捕获到什么抛出什么
//		} 
//		// ...
//
//		cout << "delete []" << array1 << endl;
//		delete[] array1;
//
//		cout << "delete []" << array2 << endl;
//		delete[] array2;
//} 
//int main()
//{
//	try
//	{
//		Func();
//	} 
//	catch(const char* errmsg)
//	{
//		cout << errmsg << endl;
//	} 
//	catch(const exception & e)
//	{
//		cout << e.what() << endl;
//	} 
//	catch(...)
//	{
//		cout << "未知异常" << endl;
//	} 
//	return 0;
//}


//struct TreeNode
//{
//	int val;
//	TreeNode* left;
//	TreeNode* right;
//	TreeNode(int x)
//		:val(x)
//		, left(nullptr)
//		, right(nullptr)
//	{}
//	TreeNode(int x, TreeNode* l, TreeNode* r)
//		:val(x)
//		, left(l)
//		, right(r)
//	{}
//};
//void inorder(TreeNode* root)
//{
//	if (!root)
//	{
//		cout << "# ";
//		return;
//	}
//	cout << root->val << " ";
//	inorder(root->left);
//	inorder(root->right);
//
//}
//class Solution
//{
//public:
//	TreeNode* TreeBiuld(vector<int>& preOrder, vector<int>& vinOrder)
//	{
//		vector<int>& v1 = preOrder;
//		vector<int>& v2 = vinOrder;
//		int n1 = v1.size();
//		int n2 = v2.size();
//		if (n1 == 0 || n2 == 0)
//		{
//			return nullptr;
//		}
//		stack<TreeNode*> st;
//		TreeNode* root = new TreeNode(v1[0]);
//		TreeNode* cur = root;
//		for (int i = 1, j = 0; i < n1; i++)
//		{
//			if (cur->val != v2[j])
//			{
//				cur->left = new TreeNode(v1[i]);
//				st.emplace(cur);
//				cur = cur->left;
//			}
//			else
//			{
//				j++;
//				while (!st.empty() && st.top()->val == v2[j])
//				{
//					cur = st.top();
//					st.pop();
//					j++;
//				}
//				// 添加右节点
//				cur->right = new TreeNode(v1[i]);
//				cur = cur->right;
//			}
//		}
//		return root;
//	}
//	vector<int> rightSideView(TreeNode* root)
//	{
//		//右边最大深处的值
//		unordered_map<int, int> mp;
//		//记录最大深度
//		int max_depth = -1;
//		//维护深度访问节点
//		stack<TreeNode*> nodes;
//		//维护dfs时的深度
//		stack<int> depths;
//		nodes.push(root);
//		depths.emplace(0);
//		while (!nodes.empty())
//		{
//			TreeNode* cur = nodes.top();
//			nodes.pop();
//			int depth = depths.top();
//			depths.pop();
//			if (cur != nullptr)
//			{
//				//维护二叉树的最大深度
//				max_depth = max(max_depth, depth);
//				if (mp.find(depth) == mp.end())
//					mp[depth] = cur->val;
//				nodes.emplace(cur->left);
//				nodes.emplace(cur->right);
//				depths.emplace(depth + 1);
//				depths.emplace(depth + 1);
//			}
//		}
//		vector<int> res;
//		for (int i = 0; i <= max_depth; i++)
//		{
//			res.emplace_back(mp[i]);
//		}
//		return res;
//	}
//	vector<int> solve(vector<int>& preOrder, vector<int>& inOrder)
//	{
//		vector<int> v;
//		if (preOrder.size() == 0 || inOrder.size() == 0)
//		{
//			return v;
//		}
//		TreeNode* root = TreeBiuld(preOrder, inOrder);
//		//inorder(root);
//		v = rightSideView(root);
//		return v;
//	}
//};
//
//int main()
//{
//	vector<int> v1{ 1,2,4,5,3 };
//	vector<int> v2{ 4,2,5,1,3 };
//
//	Solution xz;
//	vector<int> v = xz.solve(v1, v2);
//
//	for (auto e : v)
//	{
//		cout << e << " ";
//	}
//
//	return 0;
//}



//#define _CRT_SECURE_NO_WARNINGS 1
//#include <iostream>
//
//using namespace std;
//#include"string.h"

//string addStrings(string num1, string num2)
//{
//	string str;
//	int end1 = num1.size() - 1;
//	int end2 = num2.size() - 1;
//	int next = 0;
//	while (end1 >= 0 || end2 >= 0)
//	{
//		int val1 = end1 >= 0 ? num1[end1--] - '0' : 0;
//		int val2 = end2 >= 0 ? num1[end2--] - '0' : 0;
//
//		int ret = val1 + val2 + next;
//		next = ret / 10;
//		ret = ret % 10;
//
//		str += ('0' + ret);
//	}
//	if (next == 1)
//		str += '1';
//
//	reverse(str.begin(), str.end());
//	return str;
//}



//
//int main()
//{
//	xz::string ret = xz::addStrings("11111", "2222");
//	cout << ret.c_str() << endl;
//
//	return 0;
//}